Attribute VB_Name = "modClientTCP"
'    Copyright 2010 ScriptWisdom
'    This file is part of the Greentail Engine.
'
'    Greentail Engine is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 3 of the License, or
'    (at your option) any later version.
'
'    Greentail Engine is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.
'
'    You should have received a copy of the GNU General Public License
'    along with Greentail Engine.  If not, see <http://www.gnu.org/licenses/>.

Option Explicit

Public ServerIP As String
Public PlayerBuffer As String
Public InGame As Boolean
Public TradePlayer As Long

Sub TcpInit()
    SEP_CHAR = Chr(169)
    END_CHAR = Chr(237)
    PlayerBuffer = vbNullString
    frmMirage.Socket.RemoteHost = "localhost"
If FileExist("client.ini") Then
If ReadINI("CLIENT", "Server", App.Path & "\client.ini") = 0 Then
    frmMirage.Socket.RemotePort = 4000
Else
    frmMirage.Socket.RemotePort = 4050
End If
Else
    frmMirage.Socket.RemotePort = 4000
End If

End Sub

Sub TcpDestroy()
    frmMirage.Socket.Close
    
    If frmChars.Visible Then frmChars.Visible = False
    If frmCredits.Visible Then frmCredits.Visible = False
    If frmDeleteAccount.Visible Then frmDeleteAccount.Visible = False
    If frmLogin.Visible Then frmLogin.Visible = False
    If frmNewAccount.Visible Then frmNewAccount.Visible = False
    If frmNewChar.Visible Then frmNewChar.Visible = False
End Sub

Sub IncomingData(ByVal DataLength As Long)
Dim Buffer As String
Dim Packet As String
Dim tOp As String * 3
Dim Start As Long

    frmMirage.Socket.GetData Buffer, vbString, DataLength
    PlayerBuffer = PlayerBuffer & Buffer
        
    Start = InStr(PlayerBuffer, END_CHAR)
    Do While Start > 0
        Packet = Mid$(PlayerBuffer, 1, Start - 1)
        PlayerBuffer = Mid$(PlayerBuffer, Start + 1, Len(PlayerBuffer))
        Start = InStr(PlayerBuffer, END_CHAR)
        If Len(Packet) > 0 Then
            Call HandleData(Packet)
        End If
    Loop
End Sub

Sub HandleData(ByVal data As String)
Dim Parse() As String
Dim name As String
Dim Password As String
Dim Sex As Long
Dim ClassNum As Long
Dim CharNum As Long
Dim Msg As String
Dim IPMask As String
Dim BanSlot As Long
Dim MsgTo As Long
Dim Dir As Long
Dim InvNum As Long
Dim Ammount As Long
Dim Damage As Long
Dim PointType As Long
Dim BanPlayer As Long
Dim Level As Long
Dim profiletextdata As Long
Dim I As Long, n As Long, x As Long, y As Long, p As Long
Dim ShopNum As Long, GiveItem As Long, GiveValue As Long, GetItem As Long, GetValue As Long, TradeSReq As Long
Dim z As Long
Dim PartyID As Long

    ' Handle Data
    Parse = Split(data, SEP_CHAR)
    
    ' :::::::::::::::::::::::
    ' :: Get players stats ::
    ' :::::::::::::::::::::::
    If LCase04(Parse$(0)) = "maxinfo" Then
        GAME_NAME = Trim$(Parse$(1))
        MAX_PLAYERS = Val(Parse$(2))
        MAX_ITEMS = Val(Parse$(3))
        MAX_NPCS = Val(Parse$(4))
        MAX_SHOPS = Val(Parse$(5))
        MAX_SPELLS = Val(Parse$(6))
        MAX_MAPS = Val(Parse$(7))
        MAX_MAP_ITEMS = Val(Parse$(8))
        MAX_MAPX = Val(Parse$(9))
        MAX_MAPY = Val(Parse$(10))
        MAX_EMOTICONS = Val(Parse$(11))
        MAX_SPEECH = Val(Parse$(12))
        
        ReDim Map(1 To MAX_MAPS) As MapRec
        ReDim Player(1 To MAX_PLAYERS) As PlayerRec
        ReDim Item(1 To MAX_ITEMS) As ItemRec
        ReDim Npc(1 To MAX_NPCS) As NpcRec
        ReDim MapItem(1 To MAX_MAP_ITEMS) As MapItemRec
        ReDim Shop(1 To MAX_SHOPS) As ShopRec
        ReDim Spell(1 To MAX_SPELLS) As SpellRec
        ReDim Bubble(1 To MAX_PLAYERS) As ChatBubble
        ReDim SaveMapItem(1 To MAX_MAP_ITEMS) As MapItemRec
        For I = 1 To MAX_MAPS
            ReDim Map(I).Tile(0 To MAX_MAPX, 0 To MAX_MAPY) As TileRec
            ReDim Map(I).Tile(0 To MAX_MAPX, 0 To MAX_MAPY) As TileRec
        Next
        ReDim TempTile(0 To MAX_MAPX, 0 To MAX_MAPY) As TempTileRec
        ReDim Emoticons(0 To MAX_EMOTICONS) As EmoRec
        ReDim MapReport(1 To MAX_MAPS) As MapRec
        MAX_SPELL_ANIM = MAX_MAPX * MAX_MAPY
        
        ReDim Speech(1 To MAX_SPEECH) As SpeechRec
        
        MAX_BLT_LINE = 6
        ReDim BattlePMsg(1 To MAX_BLT_LINE) As BattleMsgRec
        ReDim BattleMMsg(1 To MAX_BLT_LINE) As BattleMsgRec
        
        For I = 1 To MAX_PLAYERS
            ReDim Player(I).SpellAnim(1 To MAX_SPELL_ANIM) As SpellAnimRec
        Next
        
        For I = 0 To MAX_EMOTICONS
            Emoticons(I).pic = 0
            Emoticons(I).Command = vbNullString
        Next
        
        Call ClearTempTile
        Call ClearSpeeches
        
        ' Clear out players
        For I = 1 To MAX_PLAYERS
            Call ClearPlayer(I)
        Next
        
        For I = 1 To MAX_MAPS
            Call LoadMap(I)
        Next
        
        If GetPlayerPOINTS(MyIndex) > 0 Then
            frmMirage.AddStr.Visible = False
            frmMirage.AddDef.Visible = False
            frmMirage.AddMagi.Visible = False
        End If
    
        frmMirage.Caption = Trim$(GAME_NAME)
        App.Title = GAME_NAME
 
        Exit Sub
    End If
        
    ' :::::::::::::::::::
    ' :: Npc hp packet ::
    ' :::::::::::::::::::
    If LCase04(Parse$(0)) = "npchp" Then
        n = Val(Parse$(1))
 
        MapNpc(n).HP = Val(Parse$(2))
        MapNpc(n).MaxHp = Val(Parse$(3))
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::
    ' :: Alert message packet ::
    ' ::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "alertmsg" Then
        frmMirage.picScreen.left = 8
        frmMirage.picScreen.tOp = 8
        frmMirage.picScreen.Width = 634
        frmMirage.picScreen.Height = 479
        frmMirage.Height = 9495
        frmMirage.Width = 12885
        frmMirage.Checkwindow.Enabled = False
        frmMirage.CheatCheck.Enabled = False
        frmMirage.Visible = False
        frmSendGetData.Visible = False
        frmMainMenu.Visible = True
        frmMirage.Checkwindow.Enabled = False
        frmMirage.CheatCheck.Enabled = False
        If frmPlayerChat.Visible = True Then
            Call SendData("qchat" & SEP_CHAR & END_CHAR)
        End If
        frmMirage.txtMyTextBox.Text = vbNullString
        frmMirage.txtChat.Text = vbNullString
        frmPlayerChat.txtChat.Text = vbNullString
        frmPlayerChat.txtSay.Text = vbNullString
        DoEvents

        Msg = Parse$(1)
        Call MsgBox(Msg, vbOKOnly, GAME_NAME)
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::
    ' :: Plain message packet ::
    ' ::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "plainmsg" Then
        frmSendGetData.Visible = False
        n = Val(Parse$(2))
        
        If n = 1 Then frmNewAccount.Show
        If n = 2 Then frmDeleteAccount.Show
        If n = 3 Then frmLogin.Show
        If n = 4 Then frmNewChar.Show
        If n = 5 Then frmChars.Show
        
        Msg = Parse$(1)
        Call MsgBox(Msg, vbOKOnly, GAME_NAME)
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::
    ' :: All characters packet ::
    ' :::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "allchars" Then
        n = 1
        
        frmChars.Visible = True
        frmSendGetData.Visible = False
        
        frmChars.lstChars.Clear
        
        For I = 1 To MAX_CHARS
            name = Parse$(n)
            Msg = Parse$(n + 1)
            Level = Val(Parse$(n + 2))
            
            If Trim$(name) = vbNullString Then
                frmChars.lstChars.AddItem "Free Character Slot"
            Else
                frmChars.lstChars.AddItem name & " a level " & Level & " " & Msg
            End If
            
            n = n + 3
        Next
        
        frmChars.lstChars.ListIndex = 0
        Exit Sub
    End If

    ' :::::::::::::::::::::::::::::::::
    ' :: Login was successful packet ::
    ' :::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "loginok" Then
        ' Now we can receive game data
        MyIndex = Val(Parse$(1))
        
        frmSendGetData.Visible = True
        frmChars.Visible = False
        
        Call SetStatus("Receiving game data...")
        Exit Sub
    End If
    
    ' :::::::::::::::::
    ' :: MOTD Packet ::
    ' :::::::::::::::::
    If LCase04(Parse$(0)) = "motdbox" Then
    Dim MOTDLbl2 As String
    Dim MOTDLbl3 As String
    Dim MOTDBox1 As String
    Dim MOTDBox2 As String
    MOTDLbl2 = Parse$(1)
    MOTDLbl3 = Parse$(2)
    MOTDBox1 = Parse$(3)
    MOTDBox2 = Parse$(4)
        
    frmMirage.MOTDBoxPic.Visible = True
    frmMirage.MOTDLbl2.Caption = MOTDLbl2
    frmMirage.MOTDLbl3.Caption = MOTDLbl3
    frmMirage.MOTD1Text.Text = MOTDBox1
    frmMirage.MOTD2Text.Text = MOTDBox2
        Exit Sub
    End If

    ' ::::::::::::::::::::
    ' :: Profile Packet ::
    ' ::::::::::::::::::::
    If LCase04(Parse$(0)) = "profile" Then
    Dim ProfileName As String
    Dim ProfileText As String
    Dim IsYourProfile As Byte
    ProfileName = Parse$(1)
    ProfileText = Parse$(2)
    IsYourProfile = Val(Parse$(3))
    
    If IsYourProfile = 0 Then
        frmMirage.Command3.Visible = True
        frmMirage.Status.Caption = "Status: Your Profile"
        frmMirage.ProfileText.Visible = False
        frmMirage.txtProfile.Visible = True
    End If
    
    frmMirage.Picture11.Visible = True
    frmMirage.playername1.Caption = ProfileName
    frmMirage.txtProfile.Visible = True
    frmMirage.txtProfile.Text = ProfileText
    frmMirage.ProfileText.Text = ProfileText
    
    If IsYourProfile = 1 Then
    frmMirage.Command3.Visible = False
        frmMirage.Status.Caption = "Status: " & ProfileName & "'s Profile"
        frmMirage.ProfileText.Visible = True
        frmMirage.txtProfile.Visible = False
    End If

        Exit Sub
    End If
    
    ' :::::::::::::::::::
    ' :: Target Packet ::
    ' :::::::::::::::::::
    If LCase04(Parse$(0)) = "target" Then
    Dim Target As String
    Target = Trim$(Parse$(1))
        frmMirage.LabelTarget.Caption = "Target: " & Target
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::::::::::::
    ' :: New character classes data packet ::
    ' :::::::::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "newcharclasses" Then
        n = 1
        
        ' Max classes
        Max_Classes = Val(Parse$(n))
        ReDim Class(0 To Max_Classes) As ClassRec
        
        n = n + 1

        For I = 0 To Max_Classes
            Class(I).name = Parse$(n)
            
            Class(I).HP = Val(Parse$(n + 1))
            Class(I).MP = Val(Parse$(n + 2))
            Class(I).SP = Val(Parse$(n + 3))
            
            Class(I).STR = Val(Parse$(n + 4))
            Class(I).DEF = Val(Parse$(n + 5))
            Class(I).speed = Val(Parse$(n + 6))
            Class(I).MAGI = Val(Parse$(n + 7))
            'Class(i).INTEL = Val(Parse$(n + 8))
            Class(I).MaleSprite = Val(Parse$(n + 8))
            Class(I).FemaleSprite = Val(Parse$(n + 9))
            Class(I).Locked = Val(Parse$(n + 10))
        
        n = n + 11
        Next
        
        ' Used for if the player is creating a new character
        frmNewChar.Visible = True
        frmSendGetData.Visible = False

        frmNewChar.cmbClass.Clear
        For I = 0 To Max_Classes
            If Class(I).Locked = 0 Then
                frmNewChar.cmbClass.AddItem Trim$(Class(I).name)
            End If
        Next

        frmNewChar.MaleFemale.ListIndex = 0
        
        frmNewChar.cmbClass.ListIndex = 0
        frmNewChar.lblHP.Caption = STR(Class(0).HP)
        frmNewChar.lblMP.Caption = STR(Class(0).MP)
        frmNewChar.lblSP.Caption = STR(Class(0).SP)
    
        frmNewChar.lblSTR.Caption = STR(Class(0).STR)
        frmNewChar.lblDEF.Caption = STR(Class(0).DEF)
        frmNewChar.lblMAGI.Caption = STR(Class(0).MAGI)
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::
    ' :: Classes data packet ::
    ' :::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "classesdata" Then
        n = 1
        
        ' Max classes
        Max_Classes = Val(Parse$(n))
        ReDim Class(0 To Max_Classes) As ClassRec
        
        n = n + 1
        
        For I = 0 To Max_Classes
            Class(I).name = Parse$(n)
            
            Class(I).HP = Val(Parse$(n + 1))
            Class(I).MP = Val(Parse$(n + 2))
            Class(I).SP = Val(Parse$(n + 3))
            
            Class(I).STR = Val(Parse$(n + 4))
            Class(I).DEF = Val(Parse$(n + 5))
            Class(I).speed = Val(Parse$(n + 6))
            Class(I).MAGI = Val(Parse$(n + 7))
            
            Class(I).Locked = Val(Parse$(n + 8))
            
            n = n + 9
        Next
        Exit Sub
    End If
    
    
    ' ::::::::::::::::::::
    ' :: In game packet ::
    ' ::::::::::::::::::::
    If LCase04(Parse$(0)) = "ingame" Then
        InGame = True
        Call GameInit
        Call GameLoop
        If Parse$(1) = END_CHAR Then
            MsgBox ("here")
            End
        End If
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::
    ' :: Player inventory packet ::
    ' :::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerinv" Then
        n = 2
        z = Val(Parse$(1))
        
        For I = 1 To MAX_INV
            Call SetPlayerInvItemNum(z, I, Val(Parse$(n)))
            Call SetPlayerInvItemValue(z, I, Val(Parse$(n + 1)))
            Call SetPlayerInvItemDur(z, I, Val(Parse$(n + 2)))
            
            n = n + 3
        Next
        
        If z = MyIndex Then Call UpdateVisInv
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::::::::::
    ' :: Player inventory update packet ::
    ' ::::::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerinvupdate" Then
        n = Val(Parse$(1))
        z = Val(Parse$(2))
        
        Call SetPlayerInvItemNum(z, n, Val(Parse$(3)))
        Call SetPlayerInvItemValue(z, n, Val(Parse$(4)))
        Call SetPlayerInvItemDur(z, n, Val(Parse$(5)))
        If z = MyIndex Then Call UpdateVisInv
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::::::::
    ' :: Player worn equipment packet ::
    ' ::::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerworneq" Then
        z = Val(Parse$(1))
        If z <= 0 Then Exit Sub
        
        Call SetPlayerArmorSlot(z, Val(Parse$(2)))
        Call SetPlayerWeaponSlot(z, Val(Parse$(3)))
        Call SetPlayerHelmetSlot(z, Val(Parse$(4)))
        Call SetPlayerShieldSlot(z, Val(Parse$(5)))
        
        If z = MyIndex Then
            Call UpdateVisInv
        End If
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Player bank packet ::
    ' ::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerbank" Then
        n = 1
        For I = 1 To MAX_BANK
            Call SetPlayerBankItemNum(MyIndex, I, Val(Parse$(n)))
            Call SetPlayerBankItemValue(MyIndex, I, Val(Parse$(n + 1)))
            Call SetPlayerBankItemDur(MyIndex, I, Val(Parse$(n + 2)))
            
            n = n + 3
        Next
        
        If frmBank.Visible = True Then
        Call UpdateBank
        End If
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::::
    ' :: Player bank update packet ::
    ' :::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerbankupdate" Then
        n = Val(Parse$(1))
        
        Call SetPlayerBankItemNum(MyIndex, n, Val(Parse$(2)))
        Call SetPlayerBankItemValue(MyIndex, n, Val(Parse$(3)))
        Call SetPlayerBankItemDur(MyIndex, n, Val(Parse$(4)))
        If frmBank.Visible = True Then
        Call UpdateBank
        End If
        Exit Sub
    End If
    
        If LCase04(Parse$(0)) = "opensell" Then
frmSellItem.lstSellItem.Clear
   
   For I = 1 To MAX_INV
          If GetPlayerInvItemNum(MyIndex, I) > 0 Then
                   If Item(GetPlayerInvItemNum(MyIndex, I)).Type = ITEM_TYPE_CURRENCY Then
                    frmSellItem.lstSellItem.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name) & " (" & GetPlayerInvItemValue(MyIndex, I) & ")"
                Else
                    If GetPlayerWeaponSlot(MyIndex) = I Or GetPlayerArmorSlot(MyIndex) = I Or GetPlayerHelmetSlot(MyIndex) = I Or GetPlayerShieldSlot(MyIndex) = I Then
                        frmSellItem.lstSellItem.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name) & " (worn)"
                    Else
                        frmSellItem.lstSellItem.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name)
                    End If
                End If
                       Else
           frmSellItem.lstSellItem.AddItem I & "> Empty"
       End If
   Next
   frmSellItem.lstSellItem.ListIndex = 0
   frmSellItem.Show vbModal
        Exit Sub
    End If
    
    
        If LCase04(Parse$(0)) = "updatesell" Then
   frmSellItem.lstSellItem.Clear
   For I = 1 To MAX_INV
          If GetPlayerInvItemNum(MyIndex, I) > 0 Then
                   If Item(GetPlayerInvItemNum(MyIndex, I)).Type = ITEM_TYPE_CURRENCY Then
                    frmSellItem.lstSellItem.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name) & " (" & GetPlayerInvItemValue(MyIndex, I) & ")"
                Else
                    If GetPlayerWeaponSlot(MyIndex) = I Or GetPlayerArmorSlot(MyIndex) = I Or GetPlayerHelmetSlot(MyIndex) = I Or GetPlayerShieldSlot(MyIndex) = I Then
                        frmSellItem.lstSellItem.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name) & " (worn)"
                    Else
                        frmSellItem.lstSellItem.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name)
                    End If
                End If
                       Else
           frmSellItem.lstSellItem.AddItem I & "> Empty"
       End If
   Next
   frmSellItem.lstSellItem.ListIndex = 0
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "openbank" Then
        frmBank.lblBank.Caption = Trim$(Map(GetPlayerMap(MyIndex)).name)
        frmBank.lstInventory.Clear
        frmBank.lstBank.Clear
        For I = 1 To MAX_INV
            If GetPlayerInvItemNum(MyIndex, I) > 0 Then
                If Item(GetPlayerInvItemNum(MyIndex, I)).Type = ITEM_TYPE_CURRENCY Then
                    frmBank.lstInventory.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name) & " (" & GetPlayerInvItemValue(MyIndex, I) & ")"
                Else
                    If GetPlayerWeaponSlot(MyIndex) = I Or GetPlayerArmorSlot(MyIndex) = I Or GetPlayerHelmetSlot(MyIndex) = I Or GetPlayerShieldSlot(MyIndex) = I Then
                        frmBank.lstInventory.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name) & " (worn)"
                    Else
                        frmBank.lstInventory.AddItem I & "> " & Trim$(Item(GetPlayerInvItemNum(MyIndex, I)).name)
                    End If
                End If
            Else
                frmBank.lstInventory.AddItem I & "> Empty"
            End If
            DoEvents
        Next
        
        For I = 1 To MAX_BANK
            If GetPlayerBankItemNum(MyIndex, I) > 0 Then
                If Item(GetPlayerBankItemNum(MyIndex, I)).Type = ITEM_TYPE_CURRENCY Then
                    frmBank.lstBank.AddItem I & "> " & Trim$(Item(GetPlayerBankItemNum(MyIndex, I)).name) & " (" & GetPlayerBankItemValue(MyIndex, I) & ")"
                Else
                    If GetPlayerWeaponSlot(MyIndex) = I Or GetPlayerArmorSlot(MyIndex) = I Or GetPlayerHelmetSlot(MyIndex) = I Or GetPlayerShieldSlot(MyIndex) = I Then
                        frmBank.lstBank.AddItem I & "> " & Trim$(Item(GetPlayerBankItemNum(MyIndex, I)).name) ' & " (worn)"
                    Else
                        frmBank.lstBank.AddItem I & "> " & Trim$(Item(GetPlayerBankItemNum(MyIndex, I)).name)
                    End If
                End If
            Else
                frmBank.lstBank.AddItem I & "> Empty"
            End If
            DoEvents
        Next
        frmBank.lstBank.ListIndex = 0
        frmBank.lstInventory.ListIndex = 0
        
        'frmMirage.Show vbModal = False
        frmBank.Show vbModal
        'frmBank.Visible = True
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "bankmsg" Then
        frmBank.lblMsg.Caption = Trim$(Parse$(1))
        Exit Sub
    End If
       
    Dim ShapeW As Long
    ShapeW = 191
    
    ' ::::::::::::::::::::::::::
    ' :: Player points packet ::
    ' ::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerpoints" Then
        Call SetPlayerPOINTS(MyIndex, Val(Parse$(1)))
        Exit Sub
    End If
        
    ' ::::::::::::::::::::::
    ' :: Player hp packet ::
    ' ::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerhp" Then
        Player(Val(Parse$(3))).MaxHp = Val(Parse$(1))
        Call SetPlayerHP(Val(Parse$(3)), Val(Parse$(2)))
        If MyIndex = Val(Parse$(3)) Then
            If GetPlayerMaxHP(MyIndex) > 0 Then
                frmMirage.shpHP.FillColor = RGB(208, 11, 0)
                frmMirage.shpHP.Width = (((GetPlayerHP(MyIndex) / 126) / (GetPlayerMaxHP(MyIndex) / 126)) * 126)
                frmMirage.lblHP.Caption = GetPlayerHP(MyIndex) & " / " & GetPlayerMaxHP(MyIndex)
            End If
        End If
        Exit Sub
    End If

    ' ::::::::::::::::::::::
    ' :: Player mp packet ::
    ' ::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playermp" Then
        Player(Val(Parse$(3))).MaxMP = Val(Parse$(1))
        Call SetPlayerMP(Val(Parse$(3)), Val(Parse$(2)))
        If MyIndex = Val(Parse$(3)) And GetPlayerMaxMP(MyIndex) > 0 Then
            frmMirage.shpMP.FillColor = RGB(208, 11, 0)
            frmMirage.shpMP.Width = (((GetPlayerMP(MyIndex) / 126) / (GetPlayerMaxMP(MyIndex) / 126)) * 126)
            frmMirage.lblMP.Caption = GetPlayerMP(MyIndex) & " / " & GetPlayerMaxMP(MyIndex)
        End If
        Exit Sub
    End If
    
    ' speech bubble parse
    If (LCase04(Parse$(0)) = "mapmsg2") Then
        Bubble(Val(Parse$(2))).Text = Parse$(1)
        Bubble(Val(Parse$(2))).Created = GetTickCount()
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::
    ' :: Player sp packet ::
    ' ::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playersp" Then
       ' Player(MyIndex).MaxSP = Val(Parse$(1))
        'Call SetPlayerSP(MyIndex, Val(Parse$(2)))
        'If GetPlayerMaxSP(MyIndex) > 0 Then
            'frmMirage.lblSP.Caption = Int(GetPlayerSP(MyIndex) / GetPlayerMaxSP(MyIndex) * 100) & "%"
        'End If
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::
    ' :: Player Stats Packet ::
    ' :::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "playerstatspacket") Then
        Dim SubStr As Long, SubDef As Long, SubMagi As Long, SubSpeed As Long
        SubStr = 0
        SubDef = 0
        SubMagi = 0
        SubSpeed = 0
        
        If GetPlayerWeaponSlot(MyIndex) > 0 Then
            SubStr = SubStr + Item(GetPlayerInvItemNum(MyIndex, GetPlayerWeaponSlot(MyIndex))).AddStr
            SubDef = SubDef + Item(GetPlayerInvItemNum(MyIndex, GetPlayerWeaponSlot(MyIndex))).AddDef
            SubMagi = SubMagi + Item(GetPlayerInvItemNum(MyIndex, GetPlayerWeaponSlot(MyIndex))).AddMagi
        End If
        If GetPlayerArmorSlot(MyIndex) > 0 Then
            SubStr = SubStr + Item(GetPlayerInvItemNum(MyIndex, GetPlayerArmorSlot(MyIndex))).AddStr
            SubDef = SubDef + Item(GetPlayerInvItemNum(MyIndex, GetPlayerArmorSlot(MyIndex))).AddDef
            SubMagi = SubMagi + Item(GetPlayerInvItemNum(MyIndex, GetPlayerArmorSlot(MyIndex))).AddMagi
        End If
        If GetPlayerShieldSlot(MyIndex) > 0 Then
            SubStr = SubStr + Item(GetPlayerInvItemNum(MyIndex, GetPlayerShieldSlot(MyIndex))).AddStr
            SubDef = SubDef + Item(GetPlayerInvItemNum(MyIndex, GetPlayerShieldSlot(MyIndex))).AddDef
            SubMagi = SubMagi + Item(GetPlayerInvItemNum(MyIndex, GetPlayerShieldSlot(MyIndex))).AddMagi
        End If
        If GetPlayerHelmetSlot(MyIndex) > 0 Then
            SubStr = SubStr + Item(GetPlayerInvItemNum(MyIndex, GetPlayerHelmetSlot(MyIndex))).AddStr
            SubDef = SubDef + Item(GetPlayerInvItemNum(MyIndex, GetPlayerHelmetSlot(MyIndex))).AddDef
            SubMagi = SubMagi + Item(GetPlayerInvItemNum(MyIndex, GetPlayerHelmetSlot(MyIndex))).AddMagi
        End If
        
        If SubStr > 0 Then
            frmMirage.lblSTR.Caption = Val(Parse$(1)) - SubStr & " (+" & SubStr & ")"
        Else
            frmMirage.lblSTR.Caption = Val(Parse$(1))
        End If
        If SubDef > 0 Then
            frmMirage.lblDEF.Caption = Val(Parse$(2)) - SubDef & " (+" & SubDef & ")"
        Else
            frmMirage.lblDEF.Caption = Val(Parse$(2))
        End If
        If SubMagi > 0 Then
            frmMirage.lblMAGI.Caption = Val(Parse$(4)) - SubMagi & " (+" & SubMagi & ")"
        Else
            frmMirage.lblMAGI.Caption = Val(Parse$(4))
        End If
        frmMirage.lblEXP.Caption = Val(Parse$(6)) & " / " & Val(Parse$(5))
        
        frmMirage.shpTNL.Width = (((Val(Parse$(6)) / 127) / (Val(Parse$(5)) / 127)) * 127)
        frmMirage.lblLevel.Caption = Val(Parse$(7))
        
        Exit Sub
    End If
                

    ' ::::::::::::::::::::::::
    ' :: Player data packet ::
    ' ::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "playerdata" Then
        I = Val(Parse$(1))
        Call SetPlayerName(I, Parse$(2))
        Call SetPlayerSprite(I, Val(Parse$(3)))
        Call SetPlayerMap(I, Val(Parse$(4)))
        Call SetPlayerX(I, Val(Parse$(5)))
        Call SetPlayerY(I, Val(Parse$(6)))
        Call SetPlayerDir(I, Val(Parse$(7)))
        Call SetPlayerAccess(I, Val(Parse$(8)))
        Call SetPlayerPK(I, Val(Parse$(9)))
        Call SetPlayerGuild(I, Parse$(10))
        Call SetPlayerGuildAccess(I, Val(Parse$(11)))
        Call SetPlayerClass(I, Val(Parse$(12)))
        Player(I).PartyID2 = Val(Parse$(13))
        Call SetPlayerHP(I, Val(Parse$(14)))
        Call SetPlayerMP(I, Val(Parse$(15)))

        ' Make sure they aren't walking
        Player(I).Moving = 0
        Player(I).xOffset = 0
        Player(I).yOffset = 0
        
        ' Check if the player is the client player, and if so reset directions
        If I = MyIndex Then
            DirUp = False
            DirDown = False
            DirLeft = False
            DirRight = False
        End If
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::
    ' :: Player movement packet ::
    ' ::::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "playermove") Then
        I = Val(Parse$(1))
        x = Val(Parse$(2))
        y = Val(Parse$(3))
        Dir = Val(Parse$(4))
        n = Val(Parse$(5))

        If Dir < DIR_UP Or Dir > DIR_RIGHT Then Exit Sub

        Call SetPlayerX(I, x)
        Call SetPlayerY(I, y)
        Call SetPlayerDir(I, Dir)
                
        Player(I).xOffset = 0
        Player(I).yOffset = 0
        Player(I).Moving = n
        
        Select Case GetPlayerDir(I)
            Case DIR_UP
                Player(I).yOffset = PIC_Y
            Case DIR_DOWN
                Player(I).yOffset = PIC_Y * -1
            Case DIR_LEFT
                Player(I).xOffset = PIC_X
            Case DIR_RIGHT
                Player(I).xOffset = PIC_X * -1
        End Select
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::
    ' :: Npc movement packet ::
    ' :::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "npcmove") Then
        I = Val(Parse$(1))
        x = Val(Parse$(2))
        y = Val(Parse$(3))
        Dir = Val(Parse$(4))
        n = Val(Parse$(5))

        MapNpc(I).x = x
        MapNpc(I).y = y
        MapNpc(I).Dir = Dir
        MapNpc(I).xOffset = 0
        MapNpc(I).yOffset = 0
        MapNpc(I).Moving = n
        
        Select Case MapNpc(I).Dir
            Case DIR_UP
                MapNpc(I).yOffset = PIC_Y
            Case DIR_DOWN
                MapNpc(I).yOffset = PIC_Y * -1
            Case DIR_LEFT
                MapNpc(I).xOffset = PIC_X
            Case DIR_RIGHT
                MapNpc(I).xOffset = PIC_X * -1
        End Select
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::
    ' :: Player direction packet ::
    ' :::::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "playerdir") Then
        I = Val(Parse$(1))
        Dir = Val(Parse$(2))
        
        If Dir < DIR_UP Or Dir > DIR_RIGHT Then Exit Sub

        Call SetPlayerDir(I, Dir)
        
        Player(I).xOffset = 0
        Player(I).yOffset = 0
        Player(I).Moving = 0
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::
    ' :: NPC direction packet ::
    ' ::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "npcdir") Then
        I = Val(Parse$(1))
        Dir = Val(Parse$(2))
        MapNpc(I).Dir = Dir
        
        MapNpc(I).xOffset = 0
        MapNpc(I).yOffset = 0
        MapNpc(I).Moving = 0
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "partyupdate") Then
        I = Val(Parse$(1))
        PartyID = Val(Parse$(2))
        Player(I).PartyID2 = PartyID
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::::
    ' :: Player XY location packet ::
    ' :::::::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "playerxy") Then
        x = Val(Parse$(1))
        y = Val(Parse$(2))
        
        Call SetPlayerX(MyIndex, x)
        Call SetPlayerY(MyIndex, y)
        
        ' Make sure they aren't walking
        Player(MyIndex).Moving = 0
        Player(MyIndex).xOffset = 0
        Player(MyIndex).yOffset = 0
        
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::
    ' :: Player attack packet ::
    ' ::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "attack") Then
        I = Val(Parse$(1))
        
        ' Set player to attacking
        Player(I).Attacking = 1
        Player(I).AttackTimer = GetTickCount
        
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::
    ' :: NPC attack packet ::
    ' :::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "npcattack") Then
        I = Val(Parse$(1))
        
        ' Set player to attacking
        MapNpc(I).Attacking = 1
        MapNpc(I).AttackTimer = GetTickCount
        Exit Sub
    End If
        
    ' ::::::::::::::::::::::::::
    ' :: Check for map packet ::
    ' ::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "checkformap") Then
        ' Erase all players except self
        For I = 1 To MAX_PLAYERS
            If I <> MyIndex Then
                Call SetPlayerMap(I, 0)
            End If
        Next
        
        ' Erase all temporary tile values
        Call ClearTempTile

        ' Get map num
        x = Val(Parse$(1))
        
        ' Get revision
        y = Val(Parse$(2))
        
If FileExist("client.ini") Then
If ReadINI("CLIENT", "Server", App.Path & "\client.ini") = 1 Then
If FileExist("devmaps\map" & x & ".dat") Then
            ' Check to see if the revisions match
            If GetMapRevision(x) = y Then
                ' We do so we dont need the map
                
                ' Load the map
                'Call LoadMap(X)
                
                Call SendData("needmap" & SEP_CHAR & "no" & SEP_CHAR & END_CHAR)
                Exit Sub
            End If
        End If
        Else
        If FileExist("maps\map" & x & ".dat") Then
            ' Check to see if the revisions match
            If GetMapRevision(x) = y Then
                ' We do so we dont need the map
                
                ' Load the map
                'Call LoadMap(X)
                
                Call SendData("needmap" & SEP_CHAR & "no" & SEP_CHAR & END_CHAR)
                Exit Sub
            End If
        End If
        End If
                Else
        If FileExist("maps\map" & x & ".dat") Then
            ' Check to see if the revisions match
            If GetMapRevision(x) = y Then
                ' We do so we dont need the map
                
                ' Load the map
                'Call LoadMap(X)
                
                Call SendData("needmap" & SEP_CHAR & "no" & SEP_CHAR & END_CHAR)
                Exit Sub
            End If
        End If
        End If
        
        ' Either the revisions didn't match or we dont have the map, so we need it
        If FileExist("client.ini") Then
        If ReadINI("CLIENT", "Server", App.Path & "\client.ini") = 1 Then
        Call SendData("needmap" & SEP_CHAR & "yes" & SEP_CHAR & END_CHAR)
        End If
        End If
        Exit Sub
    End If
    
    ' :::::::::::::::::::::
    ' :: Map data packet ::
    ' :::::::::::::::::::::
    If LCase04(Parse$(0)) = "mapdata" Then
        n = 1
        
        Map(Val(Parse$(1))).name = Parse$(n + 1)
        Map(Val(Parse$(1))).Revision = Val(Parse$(n + 2))
        Map(Val(Parse$(1))).Moral = Val(Parse$(n + 3))
        Map(Val(Parse$(1))).Up = Val(Parse$(n + 4))
        Map(Val(Parse$(1))).Down = Val(Parse$(n + 5))
        Map(Val(Parse$(1))).left = Val(Parse$(n + 6))
        Map(Val(Parse$(1))).Right = Val(Parse$(n + 7))
        Map(Val(Parse$(1))).Music = Parse$(n + 8)
        Map(Val(Parse$(1))).BootMap = Val(Parse$(n + 9))
        Map(Val(Parse$(1))).BootX = Val(Parse$(n + 10))
        Map(Val(Parse$(1))).BootY = Val(Parse$(n + 11))
        Map(Val(Parse$(1))).Indoors = Val(Parse$(n + 12))
        
        n = n + 13
        
        For y = 0 To MAX_MAPY
            For x = 0 To MAX_MAPX
                Map(Val(Parse$(1))).Tile(x, y).Ground = Val(Parse$(n))
                Map(Val(Parse$(1))).Tile(x, y).Mask = Val(Parse$(n + 1))
                Map(Val(Parse$(1))).Tile(x, y).Anim = Val(Parse$(n + 2))
                Map(Val(Parse$(1))).Tile(x, y).Mask2 = Val(Parse$(n + 3))
                Map(Val(Parse$(1))).Tile(x, y).M2Anim = Val(Parse$(n + 4))
                Map(Val(Parse$(1))).Tile(x, y).Fringe = Val(Parse$(n + 5))
                Map(Val(Parse$(1))).Tile(x, y).FAnim = Val(Parse$(n + 6))
                Map(Val(Parse$(1))).Tile(x, y).Fringe2 = Val(Parse$(n + 7))
                Map(Val(Parse$(1))).Tile(x, y).F2Anim = Val(Parse$(n + 8))
                Map(Val(Parse$(1))).Tile(x, y).Type = Val(Parse$(n + 9))
                Map(Val(Parse$(1))).Tile(x, y).Data1 = Val(Parse$(n + 10))
                Map(Val(Parse$(1))).Tile(x, y).Data2 = Val(Parse$(n + 11))
                Map(Val(Parse$(1))).Tile(x, y).Data3 = Val(Parse$(n + 12))
                Map(Val(Parse$(1))).Tile(x, y).String1 = Parse$(n + 13)
                Map(Val(Parse$(1))).Tile(x, y).String2 = Parse$(n + 14)
                Map(Val(Parse$(1))).Tile(x, y).String3 = Parse$(n + 15)
                Map(Val(Parse$(1))).Tile(x, y).Light = Val(Parse$(n + 16))
                Map(Val(Parse$(1))).Tile(x, y).GroundSet = Val(Parse$(n + 17))
                Map(Val(Parse$(1))).Tile(x, y).MaskSet = Val(Parse$(n + 18))
                Map(Val(Parse$(1))).Tile(x, y).AnimSet = Val(Parse$(n + 19))
                Map(Val(Parse$(1))).Tile(x, y).Mask2Set = Val(Parse$(n + 20))
                Map(Val(Parse$(1))).Tile(x, y).M2AnimSet = Val(Parse$(n + 21))
                Map(Val(Parse$(1))).Tile(x, y).FringeSet = Val(Parse$(n + 22))
                Map(Val(Parse$(1))).Tile(x, y).FAnimSet = Val(Parse$(n + 23))
                Map(Val(Parse$(1))).Tile(x, y).Fringe2Set = Val(Parse$(n + 24))
                Map(Val(Parse$(1))).Tile(x, y).F2AnimSet = Val(Parse$(n + 25))
                
                n = n + 26
            Next
        Next
        
        For x = 1 To MAX_MAP_NPCS
            'Map(Val(Parse$(1))).Npc(x) = Val(Parse$(n))
            'n = n + 1
            Map(Val(Parse$(1))).Npc(x) = Val(Parse$(n))
            Map(Val(Parse$(1))).NpcSpawn(x).Used = Val(Parse$(n + 1))
            Map(Val(Parse$(1))).NpcSpawn(x).x = Val(Parse$(n + 2))
            Map(Val(Parse$(1))).NpcSpawn(x).y = Val(Parse$(n + 3))
            n = n + 4
        Next
                
        ' Save the map
        Call SaveLocalMap(Val(Parse$(1)))
        
        ' Check if we get a map from someone else and if we were editing a map cancel it out
        If InEditor Then
            InEditor = False
            frmMapEditor.Visible = False
            frmAttributes.Visible = False
            frmMirage.Show
            'frmMirage.picMapEditor.Visible = False
            
            If frmMapWarp.Visible Then
                Unload frmMapWarp
            End If
            
            If frmMapProperties.Visible Then
                Unload frmMapProperties
            End If
        End If
        
        Exit Sub
    End If
        
    ' :::::::::::::::::::::::::::
    ' :: Map items data packet ::
    ' :::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "mapitemdata" Then
        n = 1
        
        For I = 1 To MAX_MAP_ITEMS
            SaveMapItem(I).num = Val(Parse$(n))
            SaveMapItem(I).Value = Val(Parse$(n + 1))
            SaveMapItem(I).Dur = Val(Parse$(n + 2))
            SaveMapItem(I).x = Val(Parse$(n + 3))
            SaveMapItem(I).y = Val(Parse$(n + 4))
            
            n = n + 5
        Next
        
        Exit Sub
    End If
        
    ' :::::::::::::::::::::::::
    ' :: Map npc data packet ::
    ' :::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "mapnpcdata" Then
        n = 1
        
        For I = 1 To MAX_MAP_NPCS
            SaveMapNpc(I).num = Val(Parse$(n))
            SaveMapNpc(I).x = Val(Parse$(n + 1))
            SaveMapNpc(I).y = Val(Parse$(n + 2))
            SaveMapNpc(I).Dir = Val(Parse$(n + 3))
            
            n = n + 4
        Next
        
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::::
    ' :: Map send completed packet ::
    ' :::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "mapdone" Then
        'Map = SaveMap
        
        For I = 1 To MAX_MAP_ITEMS
            MapItem(I) = SaveMapItem(I)
        Next
        
        For I = 1 To MAX_MAP_NPCS
            MapNpc(I) = SaveMapNpc(I)
        Next
        
        GettingMap = False
        
        ' Play music
        If Trim$(Map(GetPlayerMap(MyIndex)).Music) <> "None" Then
            Call PlayMidi(Trim$(Map(GetPlayerMap(MyIndex)).Music))
        Else
            Call StopMidi
        End If
        Exit Sub
    End If
    
    ' ::::::::::::::::::::
    ' :: Social packets ::
    ' ::::::::::::::::::::
    If (LCase04(Parse$(0)) = "saymsg") Or (LCase04(Parse$(0)) = "broadcastmsg") Or (LCase04(Parse$(0)) = "globalmsg") Or (LCase04(Parse$(0)) = "playermsg") Or (LCase04(Parse$(0)) = "mapmsg") Or (LCase04(Parse$(0)) = "adminmsg") Then
        Call AddText(Parse$(1), Val(Parse$(2)))
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::
    ' :: Item spawn packet ::
    ' :::::::::::::::::::::::
    If LCase04(Parse$(0)) = "spawnitem" Then
        n = Val(Parse$(1))
        
        MapItem(n).num = Val(Parse$(2))
        MapItem(n).Value = Val(Parse$(3))
        MapItem(n).Dur = Val(Parse$(4))
        MapItem(n).x = Val(Parse$(5))
        MapItem(n).y = Val(Parse$(6))
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Item editor packet ::
    ' ::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "itemeditor") Then
        InItemsEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        ' Add the names
        For I = 1 To MAX_ITEMS
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Item(I).name)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Update item packet ::
    ' ::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "updateitem") Then
        n = Val(Parse$(1))
        
        ' Update the item
        Item(n).name = Parse$(2)
        Item(n).pic = Val(Parse$(3))
        Item(n).Type = Val(Parse$(4))
        Item(n).Data1 = Val(Parse$(5))
        Item(n).Data2 = Val(Parse$(6))
        Item(n).Data3 = Val(Parse$(7))
        Item(n).StrReq = Val(Parse$(8))
        Item(n).DefReq = Val(Parse$(9))
        Item(n).SpeedReq = Val(Parse$(10))
        Item(n).ClassReq = Val(Parse$(11))
        Item(n).AccessReq = Val(Parse$(12))
        
        Item(n).AddHP = Val(Parse$(13))
        Item(n).AddMP = Val(Parse$(14))
        Item(n).AddSP = Val(Parse$(15))
        Item(n).AddStr = Val(Parse$(16))
        Item(n).AddDef = Val(Parse$(17))
        Item(n).AddMagi = Val(Parse$(18))
        Item(n).AddSpeed = Val(Parse$(19))
        Item(n).AddEXP = Val(Parse$(20))
        Item(n).desc = Parse$(21)
        Item(n).AttackSpeed = Val(Parse$(22))
        Item(n).Price = Val(Parse$(23))
        Exit Sub
    End If
       
    ' ::::::::::::::::::::::
    ' :: Edit item packet :: <- Used for item editor admins only
    ' ::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "edititem") Then
        n = Val(Parse$(1))
        
        ' Update the item
        Item(n).name = Parse$(2)
        Item(n).pic = Val(Parse$(3))
        Item(n).Type = Val(Parse$(4))
        Item(n).Data1 = Val(Parse$(5))
        Item(n).Data2 = Val(Parse$(6))
        Item(n).Data3 = Val(Parse$(7))
        Item(n).StrReq = Val(Parse$(8))
        Item(n).DefReq = Val(Parse$(9))
        Item(n).SpeedReq = Val(Parse$(10))
        Item(n).ClassReq = Val(Parse$(11))
        Item(n).AccessReq = Val(Parse$(12))
        
        Item(n).AddHP = Val(Parse$(13))
        Item(n).AddMP = Val(Parse$(14))
        Item(n).AddSP = Val(Parse$(15))
        Item(n).AddStr = Val(Parse$(16))
        Item(n).AddDef = Val(Parse$(17))
        Item(n).AddMagi = Val(Parse$(18))
        Item(n).AddSpeed = Val(Parse$(19))
        Item(n).AddEXP = Val(Parse$(20))
        Item(n).desc = Parse$(21)
        Item(n).AttackSpeed = Val(Parse$(22))
        
        ' Initialize the item editor
        Call ItemEditorInit

Item(n).Price = Val(Parse$(23))
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::
    ' :: Npc spawn packet ::
    ' ::::::::::::::::::::::
    If LCase04(Parse$(0)) = "spawnnpc" Then
        n = Val(Parse$(1))
        
        MapNpc(n).num = Val(Parse$(2))
        MapNpc(n).x = Val(Parse$(3))
        MapNpc(n).y = Val(Parse$(4))
        MapNpc(n).Dir = Val(Parse$(5))
        MapNpc(n).Big = Val(Parse$(6))
        
        ' Client use only
        MapNpc(n).xOffset = 0
        MapNpc(n).yOffset = 0
        MapNpc(n).Moving = 0
        Exit Sub
    End If
    
    ' :::::::::::::::::::::
    ' :: Npc dead packet ::
    ' :::::::::::::::::::::
    If LCase04(Parse$(0)) = "npcdead" Then
        n = Val(Parse$(1))
        
        MapNpc(n).num = 0
        MapNpc(n).x = 0
        MapNpc(n).y = 0
        MapNpc(n).Dir = 0
        
        ' Client use only
        MapNpc(n).xOffset = 0
        MapNpc(n).yOffset = 0
        MapNpc(n).Moving = 0
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::
    ' :: Npc editor packet ::
    ' :::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "npceditor") Then
        InNpcEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        ' Add the names
        For I = 1 To MAX_NPCS
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Npc(I).name)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::
    ' :: Update npc packet ::
    ' :::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "updatenpc") Then
        n = Val(Parse$(1))
        
        ' Update the item
        Npc(n).name = Parse$(2)
        Npc(n).AttackSay = vbNullString
        Npc(n).Sprite = Val(Parse$(3))
        Npc(n).SpawnSecs = 0
        Npc(n).Behavior = 0
        Npc(n).Range = 0
        For I = 1 To MAX_NPC_DROPS
            Npc(n).ItemNPC(I).Chance = 0
            Npc(n).ItemNPC(I).ItemNum = 0
            Npc(n).ItemNPC(I).ItemValue = 0
        Next
        Npc(n).STR = 0
        Npc(n).DEF = 0
        Npc(n).speed = 0
        Npc(n).MAGI = 0
        Npc(n).Big = Val(Parse$(4))
        Npc(n).MaxHp = Val(Parse$(5))
        Npc(n).EXP = 0
        Npc(n).Speech = Val(Parse$(6))
        Exit Sub
    End If

    ' :::::::::::::::::::::
    ' :: Edit npc packet :: <- Used for item editor admins only
    ' :::::::::::::::::::::
    If (LCase04(Parse$(0)) = "editnpc") Then
        n = Val(Parse$(1))
        
        ' Update the npc
        Npc(n).name = Parse$(2)
        Npc(n).AttackSay = Parse$(3)
        Npc(n).Sprite = Val(Parse$(4))
        Npc(n).SpawnSecs = Val(Parse$(5))
        Npc(n).Behavior = Val(Parse$(6))
        Npc(n).Range = Val(Parse$(7))
        Npc(n).STR = Val(Parse$(8))
        Npc(n).DEF = Val(Parse$(9))
        Npc(n).speed = Val(Parse$(10))
        Npc(n).MAGI = Val(Parse$(11))
        Npc(n).Big = Val(Parse$(12))
        Npc(n).MaxHp = Val(Parse$(13))
        Npc(n).EXP = Val(Parse$(14))
        Npc(n).SpawnTime = Val(Parse$(15))
        z = 16
        For I = 1 To MAX_NPC_DROPS
            Npc(n).ItemNPC(I).Chance = Val(Parse$(z))
            Npc(n).ItemNPC(I).ItemNum = Val(Parse$(z + 1))
            Npc(n).ItemNPC(I).ItemValue = Val(Parse$(z + 2))
            z = z + 3
        Next
        'Since this is going AFTER Drops, we can never change MAX_NPC_DROPS, or Steelw's NPCs will have to be converted.
        Npc(n).Speech = Val(Parse$(z))
        
        ' Initialize the npc editor
        Call NpcEditorInit

        Exit Sub
    End If

    ' ::::::::::::::::::::
    ' :: Map key packet ::
    ' ::::::::::::::::::::
    If (LCase04(Parse$(0)) = "mapkey") Then
        x = Val(Parse$(1))
        y = Val(Parse$(2))
        n = Val(Parse$(3))
                
        TempTile(x, y).DoorOpen = n
        
        Exit Sub
    End If

    ' :::::::::::::::::::::
    ' :: Edit map packet ::
    ' :::::::::::::::::::::
    If (LCase04(Parse$(0)) = "editmap") Then
        Call EditorInit
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Shop editor packet ::
    ' ::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "shopeditor") Then
        InShopEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        ' Add the names
        For I = 1 To MAX_SHOPS
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Shop(I).name)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Update shop packet ::
    ' ::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "updateshop") Then
        n = Val(Parse$(1))
        
        ' Update the shop name
        Shop(n).name = Parse$(2)
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::
    ' :: Edit shop packet :: <- Used for shop editor admins only
    ' ::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "editshop") Then
        ShopNum = Val(Parse$(1))
        
        ' Update the shop
        Shop(ShopNum).name = Parse$(2)
        Shop(ShopNum).JoinSay = Parse$(3)
        Shop(ShopNum).LeaveSay = Parse$(4)
        Shop(ShopNum).FixesItems = Val(Parse$(5))
        
        n = 6
        For z = 1 To 6
            For I = 1 To MAX_TRADES
                
                GiveItem = Val(Parse$(n))
                GiveValue = Val(Parse$(n + 1))
                GetItem = Val(Parse$(n + 2))
                GetValue = Val(Parse$(n + 3))
                
                Shop(ShopNum).TradeItem(z).Value(I).GiveItem = GiveItem
                Shop(ShopNum).TradeItem(z).Value(I).GiveValue = GiveValue
                Shop(ShopNum).TradeItem(z).Value(I).GetItem = GetItem
                Shop(ShopNum).TradeItem(z).Value(I).GetValue = GetValue
                
                n = n + 4
            Next
        Next
        
        ' Initialize the shop editor
        Call ShopEditorInit

        Exit Sub
    End If

    ' :::::::::::::::::::::::::
    ' :: Spell editor packet ::
    ' :::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "spelleditor") Then
        InSpellEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        ' Add the names
        For I = 1 To MAX_SPELLS
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Spell(I).name)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Update spell packet ::
    ' ::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "updatespell") Then
        n = Val(Parse$(1))
        
        ' Update the spell name
        Spell(n).name = Parse$(2)
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::
    ' :: Edit spell packet :: <- Used for spell editor admins only
    ' :::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "editspell") Then
        n = Val(Parse$(1))
        
        ' Update the spell
        Spell(n).name = Parse$(2)
        Spell(n).ClassReq = Val(Parse$(3))
        Spell(n).LevelReq = Val(Parse$(4))
        Spell(n).Type = Val(Parse$(5))
        Spell(n).Data1 = Val(Parse$(6))
        Spell(n).Data2 = Val(Parse$(7))
        Spell(n).Data3 = Val(Parse$(8))
        Spell(n).MPCost = Val(Parse$(9))
        Spell(n).Sound = Val(Parse$(10))
        Spell(n).Range = Val(Parse$(11))
        Spell(n).SpellAnim = Val(Parse$(12))
        Spell(n).SpellTime = Val(Parse$(13))
        Spell(n).SpellDone = Val(Parse$(14))
        Spell(n).AE = Val(Parse$(15))
                        
        ' Initialize the spell editor
        Call SpellEditorInit

        Exit Sub
    End If
    
    ' ::::::::::::::::::
    ' :: Trade packet ::
    ' ::::::::::::::::::
    If (LCase04(Parse$(0)) = "trade") Then
        ShopNum = Val(Parse$(1))
        If Val(Parse$(2)) = 1 Then
            frmTrade.picFixItems.Visible = True
        Else
            frmTrade.picFixItems.Visible = False
        End If
        
        n = 3
        For z = 1 To 6
            For I = 1 To MAX_TRADES
                GiveItem = Val(Parse$(n))
                GiveValue = Val(Parse$(n + 1))
                GetItem = Val(Parse$(n + 2))
                GetValue = Val(Parse$(n + 3))
                TradeSReq = Val(Parse$(n + 4))
                
                Trade(z).Items(I).ItemGetNum = GetItem
                Trade(z).Items(I).ItemGiveNum = GiveItem
                Trade(z).Items(I).ItemGetVal = GetValue
                Trade(z).Items(I).ItemGiveVal = GiveValue
                Trade(z).Items(I).TradeSReq = TradeSReq
                
                n = n + 5
            Next
        Next
        
        Dim xx As Long
        For xx = 1 To 6
            Trade(xx).Selected = NO
        Next
        
        Trade(1).Selected = YES
                    
        frmTrade.shopType.tOp = frmTrade.Label1.tOp
        frmTrade.shopType.left = frmTrade.Label1.left
        frmTrade.shopType.Height = frmTrade.Label1.Height
        frmTrade.shopType.Width = frmTrade.Label1.Width
        Trade(1).SelectedItem = 1
        
        Call ItemSelected(1, 1)
            
        frmTrade.Show vbModeless, frmMirage
        Exit Sub
    End If
    
    ' ::::::::::::::::::
    ' :: Start Speech ::
    ' ::::::::::::::::::
    If (LCase04(Parse$(0)) = "startspeech") Then
        
        I = Val(Parse$(1))
        n = Val(Parse$(2))
        
        frmTalk.txtActual.Caption = Speech(I).num(n).Text

        frmTalk.txtActual.left = frmTalk.Picture4.left + frmTalk.Picture4.Width + 16
        
        If Speech(I).num(n).Exit = 0 Then
            If Speech(I).num(n).Respond > 0 Then
                frmTalk.lblChoice(0).Caption = Speech(I).num(n).Responces(1).Text
            Else
                frmTalk.lblChoice(0).Caption = vbNullString
            End If
        
            If Speech(I).num(n).Respond > 1 Then
                frmTalk.lblChoice(1).Caption = Speech(I).num(n).Responces(2).Text
            Else
                frmTalk.lblChoice(1).Caption = vbNullString
            End If
        
            If Speech(I).num(n).Respond > 2 Then
                frmTalk.lblChoice(2).Caption = Speech(I).num(n).Responces(3).Text
            Else
                frmTalk.lblChoice(2).Caption = vbNullString
            End If
        Else
            frmTalk.lblChoice(0).Caption = vbNullString
            frmTalk.lblChoice(1).Caption = vbNullString
            frmTalk.lblChoice(2).Caption = vbNullString
            frmTalk.lblQuit.Caption = "Done"
        End If
        
        SpeechConvo1 = I
        SpeechConvo2 = n
        SpeechConvo3 = Val(Parse$(3))
        
        frmTalk.Show vbModeless, frmMirage
    End If

    ' :::::::::::::::::::
    ' :: Spells packet ::
    ' :::::::::::::::::::
    If (LCase04(Parse$(0)) = "spells") Then
        
        frmMirage.picPlayerSpells.Visible = True
        frmMirage.lstSpells.Clear
        
        ' Put spells known in player record
        For I = 1 To MAX_PLAYER_SPELLS
            Player(MyIndex).Spell(I) = Val(Parse$(I))
            If Player(MyIndex).Spell(I) <> 0 Then
                frmMirage.lstSpells.AddItem I & ": " & Trim$(Spell(Player(MyIndex).Spell(I)).name)
            Else
                frmMirage.lstSpells.AddItem "<free spells slot>"
            End If
        Next
        
        frmMirage.lstSpells.ListIndex = 0
    End If

    ' ::::::::::::::::::::
    ' :: Weather packet ::
    ' ::::::::::::::::::::
    If (LCase04(Parse$(0)) = "weather") Then
        If Val(Parse$(1)) = WEATHER_RAINING And GameWeather <> WEATHER_RAINING Then
            Call AddText("You see drops of rain falling from the sky above!", BrightGreen)
        End If
        If Val(Parse$(1)) = WEATHER_THUNDER And GameWeather <> WEATHER_THUNDER Then
            Call AddText("You see thunder in the sky above!", BrightGreen)
        End If
        If Val(Parse$(1)) = WEATHER_SNOWING And GameWeather <> WEATHER_SNOWING Then
            Call AddText("You see snow falling from the sky above!", BrightGreen)
        End If
        
        If Val(Parse$(1)) = WEATHER_NONE Then
            If GameWeather = WEATHER_RAINING Then
                Call AddText("The rain beings to calm.", BrightGreen)
            ElseIf GameWeather = WEATHER_SNOWING Then
                Call AddText("The snow is melting away.", BrightGreen)
            ElseIf GameWeather = WEATHER_THUNDER Then
                Call AddText("The thunder begins to disapear.", BrightGreen)
            End If
        End If
        GameWeather = Val(Parse$(1))
        RainIntensity = Val(Parse$(2))
        If MAX_RAINDROPS <> RainIntensity Then
            MAX_RAINDROPS = RainIntensity
            ReDim DropRain(1 To MAX_RAINDROPS) As DropRainRec
            ReDim DropSnow(1 To MAX_RAINDROPS) As DropRainRec
        End If
    End If
    
    ' :::::::::::::::::::::
    ' :: Get Online List ::
    ' :::::::::::::::::::::
    If LCase04(Parse$(0)) = "onlinelist" Then
    frmMirage.lstOnline.Clear
    
        n = 2
        z = Val(Parse$(1))
        For x = n To (z + 1)
            frmMirage.lstOnline.AddItem Trim$(Parse$(n))
            n = n + 2
        Next
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::
    ' :: Blit Player Damage ::
    ' ::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "blitplayerdmg" Then
        DmgDamage = Val(Parse$(1))
        NPCWho = Val(Parse$(2))
        DmgTime = GetTickCount
        iii = 0
        Exit Sub
    End If
    
    ' :::::::::::::::::::::
    ' :: Blit NPC Damage ::
    ' :::::::::::::::::::::
    If LCase04(Parse$(0)) = "blitnpcdmg" Then
        NPCDmgDamage = Val(Parse$(1))
        NPCDmgTime = GetTickCount
        ii = 0
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::::::::::
    ' :: Retrieve the player's inventory ::
    ' :::::::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "pptrading" Then
        frmPlayerTrade.Items1.Clear
        frmPlayerTrade.Items2.Clear
        For I = 1 To MAX_PLAYER_TRADES
            Trading(I).InvNum = 0
            Trading(I).InvName = vbNullString
            Trading2(I).InvNum = 0
            Trading2(I).InvName = vbNullString
            frmPlayerTrade.Items1.AddItem I & ": <Nothing>"
            frmPlayerTrade.Items2.AddItem I & ": <Nothing>"
        Next
        
        frmPlayerTrade.Items1.ListIndex = 0
        
        Call UpdateTradeInventory
        frmPlayerTrade.Show vbModeless, frmMirage
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::::
    ' :: Stop trading with player ::
    ' ::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "qtrade" Then
        For I = 1 To MAX_PLAYER_TRADES
            Trading(I).InvNum = 0
            Trading(I).InvName = vbNullString
            Trading2(I).InvNum = 0
            Trading2(I).InvName = vbNullString
        Next
        
        frmPlayerTrade.Command1.ForeColor = &H0&
        frmPlayerTrade.Command2.ForeColor = &H0&
        
        frmPlayerTrade.Visible = False
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::::
    ' :: Stop trading with player ::
    ' ::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "updatetradeitem" Then
            n = Val(Parse$(1))
            
            Trading2(n).InvNum = Val(Parse$(2))
            Trading2(n).InvName = Parse$(3)
            
            If STR(Trading2(n).InvNum) <= 0 Then
                frmPlayerTrade.Items2.List(n - 1) = n & ": <Nothing>"
            Else
                frmPlayerTrade.Items2.List(n - 1) = n & ": " & Trim$(Trading2(n).InvName)
            End If
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::::
    ' :: Stop trading with player ::
    ' ::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "trading" Then
        n = Val(Parse$(1))
            If n = 0 Then frmPlayerTrade.Command2.ForeColor = &H0&
            If n = 1 Then frmPlayerTrade.Command2.ForeColor = &HFF00&
        Exit Sub
    End If
    
' ::::::::::::::::::::::::::
' :: Guild System Packets ::
' ::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "greq" Then
    Call SendData("acceptedgreq" & SEP_CHAR & MyIndex & SEP_CHAR & Parse$(1) & SEP_CHAR & END_CHAR)
        Exit Sub
    End If
    
' :::::::::::::::::::::::::
' :: Chat System Packets ::
' :::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "ppchatting" Then
        frmPlayerChat.txtChat.Text = vbNullString
        frmPlayerChat.txtSay.Text = vbNullString
        frmPlayerChat.Label1.Caption = "Chatting With: " & Trim$(Player(Val(Parse$(1))).name)

        frmPlayerChat.Show vbModeless, frmMirage
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "qchat" Then
        frmPlayerChat.txtChat.Text = vbNullString
        frmPlayerChat.txtSay.Text = vbNullString
        frmPlayerChat.Visible = False
        frmPlayerTrade.Command2.ForeColor = &H8000000F
        frmPlayerTrade.Command1.ForeColor = &H8000000F
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "sendchat" Then
        Dim s As String
  
        s = vbNewLine & GetPlayerName(Val(Parse$(2))) & "> " & Trim$(Parse$(1))
        frmPlayerChat.txtChat.SelStart = Len(frmPlayerChat.txtChat.Text)
        frmPlayerChat.txtChat.SelColor = QBColor(Brown)
        frmPlayerChat.txtChat.SelText = s
        frmPlayerChat.txtChat.SelStart = Len(frmPlayerChat.txtChat.Text) - 1
        Exit Sub
    End If
' :::::::::::::::::::::::::::::
' :: END Chat System Packets ::
' :::::::::::::::::::::::::::::

    ' :::::::::::::::::::::::
    ' :: Play Sound Packet ::
    ' :::::::::::::::::::::::
    If LCase04(Parse$(0)) = "sound" Then
        s = LCase04(Parse$(1))
        Select Case Trim$(s)
            Case "attack"
                Call PlaySound("sword.wav")
            Case "critical"
                Call PlaySound("critical.wav")
            Case "miss"
                Call PlaySound("miss.wav")
            Case "key"
                Call PlaySound("key.wav")
            Case "magic"
                Call PlaySound("magic" & Val(Parse$(2)) & ".wav")
            Case "warp"
                Call PlaySound("warp.wav")
            Case "pain"
                Call PlaySound("pain.wav")
            Case "soundattribute"
                Call PlaySound(Trim$(Parse$(2)))
        End Select
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::::::::::::::::::
    ' :: Sprite Change Confirmation Packet ::
    ' :::::::::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "spritechange" Then
        If Val(Parse$(1)) = 1 Then
            I = MsgBox("Would you like to buy this sprite?", 4, "Buying Sprite")
            If I = 6 Then
                Call SendData("buysprite" & SEP_CHAR & END_CHAR)
            End If
        Else
            Call SendData("buysprite" & SEP_CHAR & END_CHAR)
        End If
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::::::::::
    ' :: Change Player Direction Packet ::
    ' ::::::::::::::::::::::::::::::::::::
    If LCase04(Parse$(0)) = "changedir" Then
        Player(Val(Parse$(2))).Dir = Val(Parse$(1))
        Exit Sub
    End If
    
    ' :::::::::::::::::::
    ' :: Prompt Packet ::
    ' :::::::::::::::::::
    If LCase04(Parse$(0)) = "prompt" Then
        I = MsgBox(Trim$(Parse$(1)), vbYesNo)
        Call SendData("prompt" & SEP_CHAR & I & SEP_CHAR & Val(Parse$(2)) & SEP_CHAR & END_CHAR)
        Exit Sub
    End If
    
    
    ' ::::::::::::::::::::::::::
    ' :: Speech editor packet ::
    ' ::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "speecheditor") Then
        InSpeechEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        For I = 1 To MAX_SPEECH
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Speech(I).name)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "speech") Then
        n = Val(Parse$(1))

        Speech(n).name = Parse$(2)
        
        Dim O As Long
        p = 3
        
        For I = 0 To MAX_SPEECH_OPTIONS
            Speech(n).num(I).Exit = Val(Parse$(p))
            Speech(n).num(I).Text = Parse$(p + 1)
            Speech(n).num(I).SaidBy = Val(Parse$(p + 2))
            Speech(n).num(I).Respond = Val(Parse$(p + 3))
            Speech(n).num(I).Script = Val(Parse$(p + 4))
            
            p = p + 5
            For O = 1 To 3
                Speech(n).num(I).Responces(O).Exit = Val(Parse$(p))
                Speech(n).num(I).Responces(O).GoTo = Val(Parse$(p + 1))
                Speech(n).num(I).Responces(O).Text = Parse$(p + 2)
                p = p + 3
            Next
        Next
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "editspeech") Then
        n = Val(Parse$(1))

        Speech(n).name = Parse$(2)
        
        p = 3
        
        For I = 0 To MAX_SPEECH_OPTIONS
            Speech(n).num(I).Exit = Val(Parse$(p))
            Speech(n).num(I).Text = Parse$(p + 1)
            Speech(n).num(I).SaidBy = Val(Parse$(p + 2))
            Speech(n).num(I).Respond = Val(Parse$(p + 3))
            Speech(n).num(I).Script = Val(Parse$(p + 4))
            
            p = p + 5
            For O = 1 To 3
                Speech(n).num(I).Responces(O).Exit = Val(Parse$(p))
                Speech(n).num(I).Responces(O).GoTo = Val(Parse$(p + 1))
                Speech(n).num(I).Responces(O).Text = Parse$(p + 2)
                p = p + 3
            Next
        Next
        
        Call SpeechEditorInit
        Exit Sub
    End If

    ' ::::::::::::::::::::::::::::
    ' :: Emoticon editor packet ::
    ' ::::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "emoticoneditor") Then
        InEmoticonEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        For I = 0 To MAX_EMOTICONS
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Emoticons(I).Command)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "updateemoticon") Then
        n = Val(Parse$(1))
        
        Emoticons(n).Command = Parse$(2)
        Emoticons(n).pic = Val(Parse$(3))
        Exit Sub
    End If

    If (LCase04(Parse$(0)) = "editemoticon") Then
        n = Val(Parse$(1))

        Emoticons(n).Command = Parse$(2)
        Emoticons(n).pic = Val(Parse$(3))
        
        Call EmoticonEditorInit
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "updateemoticon") Then
        n = Val(Parse$(1))
        
        Emoticons(n).Command = Parse$(2)
        Emoticons(n).pic = Val(Parse$(3))
        Exit Sub
    End If
    
    ' ::::::::::::::::::::::::::::
    ' :: Arrow editor packet ::
    ' ::::::::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "arroweditor") Then
        InArrowEditor = True
        
        frmIndex.Show
        frmIndex.lstIndex.Clear
        
        For I = 1 To MAX_ARROWS
            frmIndex.lstIndex.AddItem I & ": " & Trim$(Arrows(I).name)
        Next
        
        frmIndex.lstIndex.ListIndex = 0
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "updatearrow") Then
        n = Val(Parse$(1))
        
        Arrows(n).name = Parse$(2)
        Arrows(n).pic = Val(Parse$(3))
        Arrows(n).Range = Val(Parse$(4))
        Arrows(n).Amount = Val(Parse$(5))
        Exit Sub
    End If

    If (LCase04(Parse$(0)) = "editarrow") Then
        n = Val(Parse$(1))

        Arrows(n).name = Parse$(2)
        
        Call ArrowEditorInit
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "updatearrow") Then
        n = Val(Parse$(1))
        
        Arrows(n).name = Parse$(2)
        Arrows(n).pic = Val(Parse$(3))
        Arrows(n).Range = Val(Parse$(4))
        Arrows(n).Amount = Val(Parse$(5))
        Exit Sub
    End If

    If (LCase04(Parse$(0)) = "checkarrows") Then
        n = Val(Parse$(1))
        z = Val(Parse$(2))
        I = Val(Parse$(3))
        p = Val(Parse$(4))
        
        For x = 1 To MAX_PLAYER_ARROWS
            If Player(n).Arrow(x).Arrow = 0 Then
                Player(n).Arrow(x).Arrow = 1
                Player(n).Arrow(x).ArrowNum = z
                Player(n).Arrow(x).ArrowAnim = Arrows(z).pic
                Player(n).Arrow(x).ArrowTime = GetTickCount
                Player(n).Arrow(x).ArrowVarX = 0
                Player(n).Arrow(x).ArrowVarY = 0
                Player(n).Arrow(x).ArrowY = GetPlayerY(n)
                Player(n).Arrow(x).ArrowX = GetPlayerX(n)
                Player(n).Arrow(x).ArrowAmount = p
                
                If I = DIR_DOWN Then
                    Player(n).Arrow(x).ArrowY = GetPlayerY(n) + 1
                    Player(n).Arrow(x).ArrowPosition = 0
                    If Player(n).Arrow(x).ArrowY - 1 > MAX_MAPY Then
                        Player(n).Arrow(x).Arrow = 0
                        Exit Sub
                    End If
                End If
                If I = DIR_UP Then
                    Player(n).Arrow(x).ArrowY = GetPlayerY(n) - 1
                    Player(n).Arrow(x).ArrowPosition = 1
                    If Player(n).Arrow(x).ArrowY + 1 < 0 Then
                        Player(n).Arrow(x).Arrow = 0
                        Exit Sub
                    End If
                End If
                If I = DIR_RIGHT Then
                    Player(n).Arrow(x).ArrowX = GetPlayerX(n) + 1
                    Player(n).Arrow(x).ArrowPosition = 2
                    If Player(n).Arrow(x).ArrowX - 1 > MAX_MAPX Then
                        Player(n).Arrow(x).Arrow = 0
                        Exit Sub
                    End If
                End If
                If I = DIR_LEFT Then
                    Player(n).Arrow(x).ArrowX = GetPlayerX(n) - 1
                    Player(n).Arrow(x).ArrowPosition = 3
                    If Player(n).Arrow(x).ArrowX + 1 < 0 Then
                        Player(n).Arrow(x).Arrow = 0
                        Exit Sub
                    End If
                End If
                Exit For
            End If
        Next
        Exit Sub
    End If

    If (LCase04(Parse$(0)) = "checksprite") Then
        n = Val(Parse$(1))
        
        Player(n).Sprite = Val(Parse$(2))
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "mapreport") Then
        n = 1
        
        frmMapReport.lstIndex.Clear
        For I = 1 To MAX_MAPS
            frmMapReport.lstIndex.AddItem I & ": " & Trim$(Parse$(n))
            n = n + 1
        Next
        
        frmMapReport.Show vbModeless, frmMirage
        Exit Sub
    End If
    
    ' :::::::::::::::::
    ' :: Time packet ::
    ' :::::::::::::::::
    If (LCase04(Parse$(0)) = "time") Then
        GameTime = Val(Parse$(1))
        If GameTime = TIME_DAY Then
            Call AddText("Day has dawned in this realm.", White)
        Else
            Call AddText("Night has fallen upon the weary eyed nightowls.", White)
        End If
        Exit Sub
    End If
    
    ' :::::::::::::::::
    ' ::WIERD! Packet::
    ' :::::::::::::::::
    If (LCase04(Parse$(0)) = "wierd") Then
        Wierd = Val(Parse$(1))
        If Wierd = 1 Then
            Call AddText("The world has gone wierd!", White)
        Else
            Call AddText("Normality has returned", White)
        End If
        
        Exit Sub
    End If
    
    ' :::::::::::::::::::::::
    ' :: Spell anim packet ::
    ' :::::::::::::::::::::::
    If (LCase04(Parse$(0)) = "spellanim") Then
        Dim SpellNum As Long
        SpellNum = Val(Parse$(1))
        
        Spell(SpellNum).SpellAnim = Val(Parse$(2))
        Spell(SpellNum).SpellTime = Val(Parse$(3))
        Spell(SpellNum).SpellDone = Val(Parse$(4))
        
        Player(Val(Parse$(5))).SpellNum = SpellNum
        
        For I = 1 To MAX_SPELL_ANIM
            If Player(Val(Parse$(5))).SpellAnim(I).CastedSpell = NO Then
                Player(Val(Parse$(5))).SpellAnim(I).SpellDone = 0
                Player(Val(Parse$(5))).SpellAnim(I).SpellVar = 0
                Player(Val(Parse$(5))).SpellAnim(I).SpellTime = GetTickCount
                Player(Val(Parse$(5))).SpellAnim(I).TargetType = Val(Parse$(6))
                Player(Val(Parse$(5))).SpellAnim(I).Target = Val(Parse$(7))
                Player(Val(Parse$(5))).SpellAnim(I).CastedSpell = YES
                Exit For
            End If
        Next
        Exit Sub
    End If
    
    If (LCase04(Parse$(0)) = "checkemoticons") Then
        n = Val(Parse$(1))
        
        Player(n).EmoticonNum = Val(Parse$(2))
        Player(n).EmoticonTime = GetTickCount
        Player(n).EmoticonVar = 0
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "levelup" Then
        Player(Val(Parse$(1))).LevelUpT = GetTickCount
        Player(Val(Parse$(1))).LevelUp = 1
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "damagedisplay" Then
        For I = 1 To MAX_BLT_LINE
            If Val(Parse$(1)) = 0 Then
                If BattlePMsg(I).Index <= 0 Then
                    BattlePMsg(I).Index = 1
                    BattlePMsg(I).Msg = Parse$(2)
                    BattlePMsg(I).Color = Val(Parse$(3))
                    BattlePMsg(I).Time = GetTickCount
                    BattlePMsg(I).done = 1
                    BattlePMsg(I).y = 0
                    Exit Sub
                Else
                    BattlePMsg(I).y = BattlePMsg(I).y - 15
                End If
            Else
                If BattleMMsg(I).Index <= 0 Then
                    BattleMMsg(I).Index = 1
                    BattleMMsg(I).Msg = Parse$(2)
                    BattleMMsg(I).Color = Val(Parse$(3))
                    BattleMMsg(I).Time = GetTickCount
                    BattleMMsg(I).done = 1
                    BattleMMsg(I).y = 0
                    Exit Sub
                Else
                    BattleMMsg(I).y = BattleMMsg(I).y - 15
                End If
            End If
        Next
        
        z = 1
        If Val(Parse$(1)) = 0 Then
            For I = 1 To MAX_BLT_LINE
                If I < MAX_BLT_LINE Then
                    If BattlePMsg(I).y < BattlePMsg(I + 1).y Then z = I
                Else
                    If BattlePMsg(I).y < BattlePMsg(1).y Then z = I
                End If
            Next
                        
            BattlePMsg(z).Index = 1
            BattlePMsg(z).Msg = Parse$(2)
            BattlePMsg(z).Color = Val(Parse$(3))
            BattlePMsg(z).Time = GetTickCount
            BattlePMsg(z).done = 1
            BattlePMsg(z).y = 0
        Else
            For I = 1 To MAX_BLT_LINE
                If I < MAX_BLT_LINE Then
                    If BattleMMsg(I).y < BattleMMsg(I + 1).y Then z = I
                Else
                    If BattleMMsg(I).y < BattleMMsg(1).y Then z = I
                End If
            Next
                        
            BattleMMsg(z).Index = 1
            BattleMMsg(z).Msg = Parse$(2)
            BattleMMsg(z).Color = Val(Parse$(3))
            BattleMMsg(z).Time = GetTickCount
            BattleMMsg(z).done = 1
            BattleMMsg(z).y = 0
        End If
        Exit Sub
    End If
    
    If LCase04(Parse$(0)) = "itembreak" Then
        ItemDur(Val(Parse$(1))).Item = Val(Parse$(2))
        ItemDur(Val(Parse$(1))).Dur = Val(Parse$(3))
        ItemDur(Val(Parse$(1))).done = 1
        Exit Sub
    End If
End Sub

Function ConnectToServer() As Boolean
Dim Wait As Long

    ' Check to see if we are already connected, if so just exit
    If IsConnected Then
        ConnectToServer = True
        Exit Function
    End If
    
    Wait = GetTickCount
    frmMirage.Socket.Close
    frmMirage.Socket.Connect
    
    ' Wait until connected or 3 seconds have passed and report the server being down
    Do While (Not IsConnected) And (GetTickCount <= Wait + 2000)
        DoEvents
    Loop
    
    If IsConnected Then
        ConnectToServer = True
    Else
        ConnectToServer = False
    End If
End Function

Function IsConnected() As Boolean
    If frmMirage.Socket.State = sckConnected Then
        IsConnected = True
    Else
        IsConnected = False
    End If
End Function

Function IsPlaying(ByVal Index As Long) As Boolean
    If GetPlayerName(Index) <> vbNullString Then
        IsPlaying = True
    Else
        IsPlaying = False
    End If
End Function

Sub SendData(ByVal data As String)
    If IsConnected Then
        frmMirage.Socket.SendData data
        DoEvents
    End If
End Sub

Sub SendNewAccount(ByVal name As String, ByVal Password As String, ByVal Email As String)
Dim Packet As String

    Packet = "newfaccountied" & SEP_CHAR & Trim$(name) & SEP_CHAR & Trim$(Password) & SEP_CHAR & Trim$(Email) & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendDelAccount(ByVal name As String, ByVal Password As String)
Dim Packet As String
    
    Packet = "delimaccounted" & SEP_CHAR & Trim$(name) & SEP_CHAR & Trim$(Password) & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendLogin(ByVal name As String, ByVal Password As String)
Dim Packet As String

    Packet = "logination" & SEP_CHAR & Trim$(name) & SEP_CHAR & Trim$(Password) & SEP_CHAR & App.Major & SEP_CHAR & App.Minor & SEP_CHAR & App.Revision & SEP_CHAR & SEC_CODE1 & SEP_CHAR & SEC_CODE2 & SEP_CHAR & SEC_CODE3 & SEP_CHAR & SEC_CODE4 & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendAddChar(ByVal name As String, ByVal Sex As Long, ByVal ClassNum As Long, ByVal Slot As Long)
Dim Packet As String

    Packet = "addachara" & SEP_CHAR & Trim$(name) & SEP_CHAR & Sex & SEP_CHAR & ClassNum & SEP_CHAR & Slot & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendDelChar(ByVal Slot As Long)
Dim Packet As String
    
    Packet = "delimbocharu" & SEP_CHAR & Slot & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendGetClasses()
Dim Packet As String

    Packet = "gatglasses" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendUseChar(ByVal CharSlot As Long)
Dim Packet As String

    Packet = "usagakarim" & SEP_CHAR & CharSlot & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SayMsg(ByVal Text As String)
Dim Packet As String

    Packet = "saymsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub GlobalMsg(ByVal Text As String)
Dim Packet As String

    Packet = "globalmsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub BroadcastMsg(ByVal Text As String)
Dim Packet As String

    Packet = "broadcastmsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub PartyMsg(ByVal Text As String)
Dim Packet As String

    Packet = "partychat" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendPartyRequest(ByVal name As String)
Dim Packet As String

    Packet = "party" & SEP_CHAR & name & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendNewParty(ByVal name As String)
Dim Packet As String

    Packet = "newparty" & SEP_CHAR & name & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendJoinParty()
Dim Packet As String

    Packet = "joinparty" & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendLeaveParty()
Dim Packet As String

    Packet = "leaveparty" & END_CHAR
    Call SendData(Packet)
End Sub

Sub GuildMsg(ByVal Text As String)
Dim Packet As String

    Packet = "guildmsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub EmoteMsg(ByVal Text As String)
Dim Packet As String

    Packet = "emotemsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub MapMsg(ByVal Text As String)
Dim Packet As String

    Packet = "mapmsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub PlayerMsg(ByVal Text As String, ByVal MsgTo As String)
Dim Packet As String

    Packet = "playermsg" & SEP_CHAR & MsgTo & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub AdminMsg(ByVal Text As String)
Dim Packet As String

    Packet = "adminmsg" & SEP_CHAR & Text & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendPlayerMove()
Dim Packet As String

    Packet = "playermove" & SEP_CHAR & GetPlayerDir(MyIndex) & SEP_CHAR & Player(MyIndex).Moving & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendPlayerDir()
Dim Packet As String

    Packet = "playerdir" & SEP_CHAR & GetPlayerDir(MyIndex) & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendPlayerRequestNewMap()
Dim Packet As String
    
    Packet = "requestnewmap" & SEP_CHAR & GetPlayerDir(MyIndex) & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendMap()
Dim Packet As String, P1 As String, P2 As String
Dim x As Long
Dim y As Long

    Packet = "MAPDATA" & SEP_CHAR & GetPlayerMap(MyIndex) & SEP_CHAR & Trim$(Map(GetPlayerMap(MyIndex)).name) & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Revision & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Moral & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Up & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Down & SEP_CHAR & Map(GetPlayerMap(MyIndex)).left & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Right & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Music & SEP_CHAR & Map(GetPlayerMap(MyIndex)).BootMap & SEP_CHAR & Map(GetPlayerMap(MyIndex)).BootX & SEP_CHAR & Map(GetPlayerMap(MyIndex)).BootY & SEP_CHAR & Map(GetPlayerMap(MyIndex)).Indoors & SEP_CHAR
    
    For y = 0 To MAX_MAPY
        For x = 0 To MAX_MAPX
            With Map(GetPlayerMap(MyIndex)).Tile(x, y)
                Packet = Packet & .Ground & SEP_CHAR & .Mask & SEP_CHAR & .Anim & SEP_CHAR & .Mask2 & SEP_CHAR & .M2Anim & SEP_CHAR & .Fringe & SEP_CHAR & .FAnim & SEP_CHAR & .Fringe2 & SEP_CHAR & .F2Anim & SEP_CHAR & .Type & SEP_CHAR & .Data1 & SEP_CHAR & .Data2 & SEP_CHAR & .Data3 & SEP_CHAR & .String1 & SEP_CHAR & .String2 & SEP_CHAR & .String3 & SEP_CHAR & .Light & SEP_CHAR
                Packet = Packet & .GroundSet & SEP_CHAR & .MaskSet & SEP_CHAR & .AnimSet & SEP_CHAR & .Mask2Set & SEP_CHAR & .M2AnimSet & SEP_CHAR & .FringeSet & SEP_CHAR & .FAnimSet & SEP_CHAR & .Fringe2Set & SEP_CHAR & .F2AnimSet & SEP_CHAR
            End With
        Next
    Next
    
    For x = 1 To MAX_MAP_NPCS
        Packet = Packet & Map(GetPlayerMap(MyIndex)).Npc(x) & SEP_CHAR
        Packet = Packet & Map(GetPlayerMap(MyIndex)).NpcSpawn(x).Used & SEP_CHAR & Map(GetPlayerMap(MyIndex)).NpcSpawn(x).x & SEP_CHAR & Map(GetPlayerMap(MyIndex)).NpcSpawn(x).y & SEP_CHAR
    Next
    
    Packet = Packet & END_CHAR
    
    x = Int(Len(Packet) / 2)
    P1 = Mid$(Packet, 1, x)
    P2 = Mid$(Packet, x + 1, Len(Packet) - x)
    Call SendData(Packet)
End Sub

Sub WarpMeTo(ByVal name As String)
Dim Packet As String

    Packet = "WARPMETO" & SEP_CHAR & name & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub WarpToMe(ByVal name As String)
Dim Packet As String

    Packet = "WARPTOME" & SEP_CHAR & name & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub WarpTo(ByVal MapNum As Long)
Dim Packet As String
    
    Packet = "WARPTO" & SEP_CHAR & MapNum & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSetAccess(ByVal name As String, ByVal Access As Byte)
Dim Packet As String

    Packet = "SETACCESS" & SEP_CHAR & name & SEP_CHAR & Access & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSetSprite(ByVal SpriteNum As Long)
Dim Packet As String

    Packet = "SETSPRITE" & SEP_CHAR & SpriteNum & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendKick(ByVal name As String)
Dim Packet As String

    Packet = "KICKPLAYER" & SEP_CHAR & name & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendBan(ByVal name As String)
Dim Packet As String

    Packet = "BANPLAYER" & SEP_CHAR & name & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendBanList()
Dim Packet As String

    Packet = "BANLIST" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestEditItem()
Dim Packet As String

    Packet = "REQUESTEDITITEM" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveItem(ByVal ItemNum As Long)
Dim Packet As String

    Packet = "SAVEITEM" & SEP_CHAR & ItemNum & SEP_CHAR & Trim$(Item(ItemNum).name) & SEP_CHAR & Item(ItemNum).pic & SEP_CHAR & Item(ItemNum).Type & SEP_CHAR & Item(ItemNum).Data1 & SEP_CHAR & Item(ItemNum).Data2 & SEP_CHAR & Item(ItemNum).Data3 & SEP_CHAR & Item(ItemNum).StrReq & SEP_CHAR & Item(ItemNum).DefReq & SEP_CHAR & Item(ItemNum).SpeedReq & SEP_CHAR & Item(ItemNum).ClassReq & SEP_CHAR & Item(ItemNum).AccessReq & SEP_CHAR
    Packet = Packet & Item(ItemNum).AddHP & SEP_CHAR & Item(ItemNum).AddMP & SEP_CHAR & Item(ItemNum).AddSP & SEP_CHAR & Item(ItemNum).AddStr & SEP_CHAR & Item(ItemNum).AddDef & SEP_CHAR & Item(ItemNum).AddMagi & SEP_CHAR & Item(ItemNum).AddSpeed & SEP_CHAR & Item(ItemNum).AddEXP & SEP_CHAR & Item(ItemNum).desc & SEP_CHAR & Item(ItemNum).AttackSpeed & SEP_CHAR & Item(ItemNum).Price
    Packet = Packet & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestEditSpeech()
Dim Packet As String

    Packet = "REQUESTEDITSPEECH" & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveSpeech(ByVal SpcNum As Long)
Dim Packet As String
Dim I, O As Long

    Packet = "SAVESPEECH" & SEP_CHAR & SpcNum & SEP_CHAR & Speech(SpcNum).name & SEP_CHAR
    For I = 0 To MAX_SPEECH_OPTIONS
        Packet = Packet & Speech(SpcNum).num(I).Exit & SEP_CHAR & Speech(SpcNum).num(I).Text & SEP_CHAR & Speech(SpcNum).num(I).SaidBy & SEP_CHAR & Speech(SpcNum).num(I).Respond & SEP_CHAR & Speech(SpcNum).num(I).Script & SEP_CHAR
        For O = 1 To 3
            Packet = Packet & Speech(SpcNum).num(I).Responces(O).Exit & SEP_CHAR & Speech(SpcNum).num(I).Responces(O).GoTo & SEP_CHAR & Speech(SpcNum).num(I).Responces(O).Text & SEP_CHAR
        Next
    Next
    Packet = Packet & END_CHAR
    Call SendData(Packet)
End Sub
                
Sub SendRequestEditEmoticon()
Dim Packet As String

    Packet = "REQUESTEDITEMOTICON" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveEmoticon(ByVal EmoNum As Long)
Dim Packet As String

    Packet = "SAVEEMOTICON" & SEP_CHAR & EmoNum & SEP_CHAR & Trim$(Emoticons(EmoNum).Command) & SEP_CHAR & Emoticons(EmoNum).pic & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestEditArrow()
Dim Packet As String

    Packet = "REQUESTEDITARROW" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveArrow(ByVal ArrowNum As Long)
Dim Packet As String

    Packet = "SAVEARROW" & SEP_CHAR & ArrowNum & SEP_CHAR & Trim$(Arrows(ArrowNum).name) & SEP_CHAR & Arrows(ArrowNum).pic & SEP_CHAR & Arrows(ArrowNum).Range & SEP_CHAR & Arrows(ArrowNum).Amount & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub
                
Sub SendRequestEditNpc()
Dim Packet As String

    Packet = "REQUESTEDITNPC" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveNpc(ByVal NpcNum As Long)
Dim Packet As String
Dim I As Long
    
    Packet = "SAVENPC" & SEP_CHAR & NpcNum & SEP_CHAR & Trim$(Npc(NpcNum).name) & SEP_CHAR & Trim$(Npc(NpcNum).AttackSay) & SEP_CHAR & Npc(NpcNum).Sprite & SEP_CHAR & Npc(NpcNum).SpawnSecs & SEP_CHAR & Npc(NpcNum).Behavior & SEP_CHAR & Npc(NpcNum).Range & SEP_CHAR & Npc(NpcNum).STR & SEP_CHAR & Npc(NpcNum).DEF & SEP_CHAR & Npc(NpcNum).speed & SEP_CHAR & Npc(NpcNum).MAGI & SEP_CHAR & Npc(NpcNum).Big & SEP_CHAR & Npc(NpcNum).MaxHp & SEP_CHAR & Npc(NpcNum).EXP & SEP_CHAR & Npc(NpcNum).SpawnTime & SEP_CHAR
    For I = 1 To MAX_NPC_DROPS
        Packet = Packet & Npc(NpcNum).ItemNPC(I).Chance
        Packet = Packet & SEP_CHAR & Npc(NpcNum).ItemNPC(I).ItemNum
        Packet = Packet & SEP_CHAR & Npc(NpcNum).ItemNPC(I).ItemValue & SEP_CHAR
    Next
    Packet = Packet & Npc(NpcNum).Speech & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendMapRespawn()
Dim Packet As String

    Packet = "MAPRESPAWN" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendUseItem(ByVal InvNum As Long)
Dim Packet As String

    Packet = "USEITEM" & SEP_CHAR & InvNum & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendDropItem(ByVal InvNum, ByVal Ammount As Long)
Dim Packet As String

    Packet = "MAPDROPITEM" & SEP_CHAR & InvNum & SEP_CHAR & Ammount & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendWhosOnline()
Dim Packet As String

    Packet = "WHOSONLINE" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub
Sub SendOnlineList()
Dim Packet As String

Packet = "ONLINELIST" & SEP_CHAR & END_CHAR
Call SendData(Packet)
End Sub
            
Sub SendMOTDChange(ByVal MOTD As String)
Dim Packet As String

    Packet = "SETMOTD" & SEP_CHAR & MOTD & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestEditShop()
Dim Packet As String

    Packet = "REQUESTEDITSHOP" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveShop(ByVal ShopNum As Long)
Dim Packet As String
Dim I As Long, z As Long

    Packet = "SAVESHOP" & SEP_CHAR & ShopNum & SEP_CHAR & Trim$(Shop(ShopNum).name) & SEP_CHAR & Trim$(Shop(ShopNum).JoinSay) & SEP_CHAR & Trim$(Shop(ShopNum).LeaveSay) & SEP_CHAR & Shop(ShopNum).FixesItems & SEP_CHAR
    For I = 1 To 6
        For z = 1 To MAX_TRADES
            Packet = Packet & Shop(ShopNum).TradeItem(I).Value(z).GiveItem & SEP_CHAR & Shop(ShopNum).TradeItem(I).Value(z).GiveValue & SEP_CHAR & Shop(ShopNum).TradeItem(I).Value(z).GetItem & SEP_CHAR & Shop(ShopNum).TradeItem(I).Value(z).GetValue & SEP_CHAR
        Next
    Next
    Packet = Packet & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestEditSpell()
Dim Packet As String

    Packet = "REQUESTEDITSPELL" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSaveSpell(ByVal SpellNum As Long)
Dim Packet As String

    Packet = "SAVESPELL" & SEP_CHAR & SpellNum & SEP_CHAR & Trim$(Spell(SpellNum).name) & SEP_CHAR & Spell(SpellNum).ClassReq & SEP_CHAR & Spell(SpellNum).LevelReq & SEP_CHAR & Spell(SpellNum).Type & SEP_CHAR & Spell(SpellNum).Data1 & SEP_CHAR & Spell(SpellNum).Data2 & SEP_CHAR & Spell(SpellNum).Data3 & SEP_CHAR & Spell(SpellNum).MPCost & SEP_CHAR & Trim$(Spell(SpellNum).Sound) & SEP_CHAR & Spell(SpellNum).Range & SEP_CHAR & Spell(SpellNum).SpellAnim & SEP_CHAR & Spell(SpellNum).SpellTime & SEP_CHAR & Spell(SpellNum).SpellDone & SEP_CHAR & Spell(SpellNum).AE & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestEditMap()
Dim Packet As String

    Packet = "REQUESTEDITMAP" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendTradeRequest(ByVal name As String)
Dim Packet As String

    Packet = "PPTRADE" & SEP_CHAR & name & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendAcceptTrade()
Dim Packet As String

    Packet = "ATRADE" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendDeclineTrade()
Dim Packet As String

    Packet = "DTRADE" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendBanDestroy()
Dim Packet As String
    
    Packet = "BANDESTROY" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendRequestLocation()
Dim Packet As String

    Packet = "REQUESTLOCATION" & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub SendSetPlayerSprite(ByVal name As String, ByVal SpriteNum As Byte)
Dim Packet As String

    Packet = "SETPLAYERSPRITE" & SEP_CHAR & name & SEP_CHAR & SpriteNum & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub

Sub Transport(ByVal MapNum As Long, ByVal MapX As Integer, ByVal MapY As Integer)
Dim Packet As String
    
    Packet = "TRANSPORT" & SEP_CHAR & MapNum & SEP_CHAR & MapX & SEP_CHAR & MapY & SEP_CHAR & END_CHAR
    Call SendData(Packet)
End Sub
